<?php

namespace app\api\controller;

use app\common\controller\Api;
use think\Config;
use think\Db;

/**
 * 食材接口
 */
class FoodIngredient extends Api
{
    // 如果不需要验证token，可以设置为false
    protected $noNeedLogin = ['*'];
    // 如果不需要验证权限，可以设置为false
    protected $noNeedRight = ['*'];
    public function demo(){

        echo 123;
        
    }
    
    /**
     * 调用千问API生成菜品与形态分类的关联语句
     * @param array $dishes 菜品数据
     * @param array $forms 形态分类数据
     * @return array SQL语句数组
     */
    private function generateFormRelationsByQwen($dishes, $forms) {
        // 阿里云千问API配置
        $apiKey = 'sk-416b931b781c420c9f6331b7346962b5';
        $apiUrl = 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions';
        $model = 'qwen-plus';
        
        // 构造菜品信息
        $dishInfo = "";
        foreach ($dishes as $dish) {
            $dishInfo .= "菜品ID: {$dish['id']}, 名称: {$dish['name']}, 制作步骤: {$dish['steps']}\n";
        }
        
        // 构造形态分类信息
        $formInfo = "";
        foreach ($forms as $form) {
            $formInfo .= "形态分类ID: {$form['id']}, 名称: {$form['name']}\n";
        }
        
        // 构造提示词
        $prompt = "根据以下菜品信息和形态分类信息，为每个菜品匹配合适的形态分类，并生成相应的MySQL插入语句：\n\n";
        $prompt .= "菜品信息：\n{$dishInfo}\n";
        $prompt .= "形态分类信息：\n{$formInfo}\n\n";
        $prompt .= "请严格按照以下JSON格式返回结果，不要包含其他内容：\n";
        $prompt .= "{\n";
        $prompt .= "  \"sql_statements\": [\n";
        $prompt .= "    \"INSERT INTO fa_food_formrel (dish_id, form_id, createtime, updatetime, weigh) VALUES (1, 5, 1234567890, 1234567890, 1);\",\n";
        $prompt .= "    \"INSERT INTO fa_food_formrel (dish_id, form_id, createtime, updatetime, weigh) VALUES (2, 3, 1234567890, 1234567890, 1);\"\n";
        $prompt .= "  ]\n";
        $prompt .= "}\n\n";
        $prompt .= "注意事项：\n";
        $prompt .= "1. 每个菜品可能匹配多个形态分类，请根据菜品的制作步骤和名称尽可能全面地匹配所有合适的形态分类\n";
        $prompt .= "2. 仔细分析菜品的食材组成和烹饪方式，确保不遗漏任何可能的形态分类，特别是以下几类容易遗漏的分类：\n";
        $prompt .= "   - 主食制品：如炒饭、面条、包子、馒头等以主食为基础的菜品\n";
        $prompt .= "   - 禽肉类：如鸡肉、鸭肉、鹅肉等禽类食材制作的菜品\n";
        $prompt .= "   - 畜肉类：如猪肉、牛肉、羊肉等畜类食材制作的菜品\n";
        $prompt .= "   - 素菜：几乎所有的蔬菜类菜品都应标记为此类\n";
        $prompt .= "   - 清真：清真食材或清真烹饪方式制作的菜品\n";
        $prompt .= "   - 自制食材：餐厅自制的食材或半成品\n";
        $prompt .= "3. 生成的SQL语句必须是INSERT INTO语句，操作的表名为fa_food_formrel\n";
        $prompt .= "4. 字段包括：dish_id, form_id, createtime, updatetime, weigh\n";
        $prompt .= "5. createtime和updatetime使用当前时间戳\n";
        $prompt .= "6. weigh字段默认为1\n";
        $prompt .= "7. 只返回标准JSON格式的数据，严格按照上面提供的JSON示例格式，不要包含任何其他说明文字、注释或额外内容，不要使用Markdown代码块标记";
        dump($prompt);
        $data = [
            'model' => $model,
            'messages' => [
                [
                    'role' => 'user',
                    'content' => $prompt
                ]
            ],
            'temperature' => 0.1,
            'max_tokens' => 30000
        ];
        
        // 发起HTTP请求
        $headers = [
            'Authorization: Bearer ' . $apiKey,
            'Content-Type: application/json'
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 1130);
        
        $response = curl_exec($ch);
        
        if (curl_errno($ch)) {
            \think\Log::error('千问API调用错误: ' . curl_error($ch));
            curl_close($ch);
            return [];
        }
        
        curl_close($ch);
        
        // 打印API返回的原始内容用于调试
        \think\Log::info('千问API返回的原始内容: ' . $response);
        dump('千问API返回的原始内容: ' . $response);
        
        $responseArr = json_decode($response, true);
        if (empty($responseArr['choices'][0]['message']['content'])) {
            \think\Log::error('千问API返回内容为空或格式不正确');
            dump('千问API返回内容为空或格式不正确');
            return [];
        }
        
        // 解析返回的JSON内容
        $content = trim($responseArr['choices'][0]['message']['content']);
        
        // 打印解析后的content内容用于调试
        \think\Log::info('千问API返回的content内容: ' . $content);
        dump('千问API返回的content内容: ' . $content);
        
        // 尝试提取JSON部分
        if (preg_match('/\{.*\}/s', $content, $matches)) {
            $jsonStr = $matches[0];
            // 打印提取的JSON字符串用于调试
            \think\Log::info('提取的JSON字符串: ' . $jsonStr);
            dump('提取的JSON字符串: ' . $jsonStr);
            
            $result = json_decode($jsonStr, true);
            if (json_last_error() === JSON_ERROR_NONE && isset($result['sql_statements'])) {
                return $result['sql_statements'];
            } else {
                \think\Log::error('JSON解析失败或缺少sql_statements字段: ' . json_last_error_msg());
                dump('JSON解析失败或缺少sql_statements字段: ' . json_last_error_msg());
            }
        } else {
            \think\Log::error('未能从返回内容中提取JSON格式数据');
            dump('未能从返回内容中提取JSON格式数据');
        }
        
        return [];
    }
    
    /**
     * 调用千问API生成菜品与人群分类的关联语句
     * @param array $dishes 菜品数据
     * @param array $crowds 人群分类数据
     * @return array SQL语句数组
     */
    private function generateCrowdRelationsByQwen($dishes, $crowds) {
        // 阿里云千问API配置
        $apiKey = 'sk-416b931b781c420c9f6331b7346962b5';
        $apiUrl = 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions';
        $model = 'qwen-plus';
        
        // 构造菜品信息
        $dishInfo = "";
        foreach ($dishes as $dish) {
            $dishInfo .= "菜品ID: {$dish['id']}, 名称: {$dish['name']}, 制作步骤: {$dish['steps']}\n";
        }
        
        // 构造人群分类信息
        $crowdInfo = "";
        foreach ($crowds as $crowd) {
            $crowdInfo .= "人群分类ID: {$crowd['id']}, 名称: {$crowd['name']}\n";
        }
        
        // 构造提示词
        $prompt = "根据以下菜品信息和人群分类信息，为每个菜品匹配合适的人群分类，并生成相应的MySQL插入语句：\n\n";
        $prompt .= "菜品信息：\n{$dishInfo}\n";
        $prompt .= "人群分类信息：\n{$crowdInfo}\n\n";
        $prompt .= "请严格按照以下JSON格式返回结果，不要包含其他内容：\n";
        $prompt .= "{\n";
        $prompt .= "  \"sql_statements\": [\n";
        $prompt .= "    \"INSERT INTO fa_food_crowdrel (dish_id, crowd_id, createtime, updatetime, weigh) VALUES (1, 5, 1234567890, 1234567890, 1);\",\n";
        $prompt .= "    \"INSERT INTO fa_food_crowdrel (dish_id, crowd_id, createtime, updatetime, weigh) VALUES (2, 3, 1234567890, 1234567890, 1);\"\n";
        $prompt .= "  ]\n";
        $prompt .= "}\n\n";
        $prompt .= "注意事项：\n";
        $prompt .= "1. 每个菜品可能匹配多个人群分类，请根据菜品的营养成分、口味特点和适用场景尽可能全面地匹配所有合适的人群分类\n";
        $prompt .= "2. 仔细分析菜品的食材组成和烹饪方式，确保不遗漏任何可能的人群分类\n";
        $prompt .= "3. 生成的SQL语句必须是INSERT INTO语句，操作的表名为fa_food_crowdrel\n";
        $prompt .= "4. 字段包括：dish_id, crowd_id, createtime, updatetime, weigh\n";
        $prompt .= "5. createtime和updatetime使用当前时间戳\n";
        $prompt .= "6. weigh字段默认为1\n";
        $prompt .= "7. 只返回标准JSON格式的数据，严格按照上面提供的JSON示例格式，不要包含任何其他说明文字、注释或额外内容，不要使用Markdown代码块标记";
        
        $data = [
            'model' => $model,
            'messages' => [
                [
                    'role' => 'user',
                    'content' => $prompt
                ]
            ],
            'temperature' => 0.1,
            'max_tokens' => 30000
        ];
        
        // 发起HTTP请求
        $headers = [
            'Authorization: Bearer ' . $apiKey,
            'Content-Type: application/json'
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 1130);
        
        $response = curl_exec($ch);
        
        if (curl_errno($ch)) {
            \think\Log::error('千问API调用错误: ' . curl_error($ch));
            curl_close($ch);
            return [];
        }
        
        curl_close($ch);
        
        // 打印API返回的原始内容用于调试
        \think\Log::info('千问API返回的原始内容: ' . $response);
        dump('千问API返回的原始内容: ' . $response);
        
        $responseArr = json_decode($response, true);
        if (empty($responseArr['choices'][0]['message']['content'])) {
            \think\Log::error('千问API返回内容为空或格式不正确');
            dump('千问API返回内容为空或格式不正确');
            return [];
        }
        
        // 解析返回的JSON内容
        $content = trim($responseArr['choices'][0]['message']['content']);
        
        // 打印解析后的content内容用于调试
        \think\Log::info('千问API返回的content内容: ' . $content);
        dump('千问API返回的content内容: ' . $content);
        
        // 尝试提取JSON部分
        if (preg_match('/\{.*\}/s', $content, $matches)) {
            $jsonStr = $matches[0];
            // 打印提取的JSON字符串用于调试
            \think\Log::info('提取的JSON字符串: ' . $jsonStr);
            dump('提取的JSON字符串: ' . $jsonStr);
            
            $result = json_decode($jsonStr, true);
            if (json_last_error() === JSON_ERROR_NONE && isset($result['sql_statements'])) {
                return $result['sql_statements'];
            } else {
                \think\Log::error('JSON解析失败或缺少sql_statements字段: ' . json_last_error_msg());
                dump('JSON解析失败或缺少sql_statements字段: ' . json_last_error_msg());
            }
        } else {
            \think\Log::error('未能从返回内容中提取JSON格式数据');
            dump('未能从返回内容中提取JSON格式数据');
        }
        
        return [];
    }
    
    /**
     * 调用千问API生成菜品与菜系分类的关联语句
     * @param array $dishes 菜品数据
     * @param array $cuisines 菜系分类数据
     * @return array SQL语句数组
     */
    private function generateCuisineRelationsByQwen($dishes, $cuisines) {
        // 阿里云千问API配置
        $apiKey = 'sk-416b931b781c420c9f6331b7346962b5';
        $apiUrl = 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions';
        $model = 'qwen-plus';
        
        // 构造菜品信息
        $dishInfo = "";
        foreach ($dishes as $dish) {
            $dishInfo .= "菜品ID: {$dish['id']}, 名称: {$dish['name']}, 制作步骤: {$dish['steps']}\n";
        }
        
        // 构造菜系分类信息
        $cuisineInfo = "";
        foreach ($cuisines as $cuisine) {
            $cuisineInfo .= "菜系分类ID: {$cuisine['id']}, 名称: {$cuisine['name']}\n";
        }
        
        // 构造提示词
        $prompt = "根据以下菜品信息和菜系分类信息，为每个菜品匹配合适的菜系分类，并生成相应的MySQL插入语句：\n\n";
        $prompt .= "菜品信息：\n{$dishInfo}\n";
        $prompt .= "菜系分类信息：\n{$cuisineInfo}\n\n";
        $prompt .= "请严格按照以下JSON格式返回结果，不要包含其他内容：\n";
        $prompt .= "{\n";
        $prompt .= "  \"sql_statements\": [\n";
        $prompt .= "    \"INSERT INTO fa_food_cuisinerel (dish_id, cuisine_id, createtime, updatetime, weigh) VALUES (1, 5, 1234567890, 1234567890, 1);\",\n";
        $prompt .= "    \"INSERT INTO fa_food_cuisinerel (dish_id, cuisine_id, createtime, updatetime, weigh) VALUES (2, 3, 1234567890, 1234567890, 1);\"\n";
        $prompt .= "  ]\n";
        $prompt .= "}\n\n";
        $prompt .= "注意事项：\n";
        $prompt .= "1. 每个菜品可能匹配多个菜系分类，请根据菜品的地域特色、烹饪技法和风味特点尽可能全面地匹配所有合适的菜系分类\n";
        $prompt .= "2. 仔细分析菜品的食材组成和烹饪方式，确保不遗漏任何可能的菜系分类\n";
        $prompt .= "3. 生成的SQL语句必须是INSERT INTO语句，操作的表名为fa_food_cuisinerel\n";
        $prompt .= "4. 字段包括：dish_id, cuisine_id, createtime, updatetime, weigh\n";
        $prompt .= "5. createtime和updatetime使用当前时间戳\n";
        $prompt .= "6. weigh字段默认为1\n";
        $prompt .= "7. 只返回标准JSON格式的数据，严格按照上面提供的JSON示例格式，不要包含任何其他说明文字、注释或额外内容，不要使用Markdown代码块标记";
        
        $data = [
            'model' => $model,
            'messages' => [
                [
                    'role' => 'user',
                    'content' => $prompt
                ]
            ],
            'temperature' => 0.1,
            'max_tokens' => 30000
        ];
        
        // 发起HTTP请求
        $headers = [
            'Authorization: Bearer ' . $apiKey,
            'Content-Type: application/json'
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 1130);
        
        $response = curl_exec($ch);
        
        if (curl_errno($ch)) {
            \think\Log::error('千问API调用错误: ' . curl_error($ch));
            curl_close($ch);
            return [];
        }
        
        curl_close($ch);
        
        // 打印API返回的原始内容用于调试
        \think\Log::info('千问API返回的原始内容: ' . $response);
        dump('千问API返回的原始内容: ' . $response);
        
        $responseArr = json_decode($response, true);
        if (empty($responseArr['choices'][0]['message']['content'])) {
            \think\Log::error('千问API返回内容为空或格式不正确');
            dump('千问API返回内容为空或格式不正确');
            return [];
        }
        
        // 解析返回的JSON内容
        $content = trim($responseArr['choices'][0]['message']['content']);
        
        // 打印解析后的content内容用于调试
        \think\Log::info('千问API返回的content内容: ' . $content);
        dump('千问API返回的content内容: ' . $content);
        
        // 尝试提取JSON部分
        if (preg_match('/\{.*\}/s', $content, $matches)) {
            $jsonStr = $matches[0];
            // 打印提取的JSON字符串用于调试
            \think\Log::info('提取的JSON字符串: ' . $jsonStr);
            dump('提取的JSON字符串: ' . $jsonStr);
            
            $result = json_decode($jsonStr, true);
            if (json_last_error() === JSON_ERROR_NONE && isset($result['sql_statements'])) {
                return $result['sql_statements'];
            } else {
                \think\Log::error('JSON解析失败或缺少sql_statements字段: ' . json_last_error_msg());
                dump('JSON解析失败或缺少sql_statements字段: ' . json_last_error_msg());
            }
        } else {
            \think\Log::error('未能从返回内容中提取JSON格式数据');
            dump('未能从返回内容中提取JSON格式数据');
        }
        
        return [];
    }
    
    /**
     * 调用千问API生成菜品与营养分类的关联语句
     * @param array $dishes 菜品数据
     * @param array $nutritions 营养分类数据
     * @return array SQL语句数组
     */
    private function generateNutritionRelationsByQwen($dishes, $nutritions) {
        // 阿里云千问API配置
        $apiKey = 'sk-416b931b781c420c9f6331b7346962b5';
        $apiUrl = 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions';
        $model = 'qwen-plus';
        
        // 构造菜品信息
        $dishInfo = "";
        foreach ($dishes as $dish) {
            $dishInfo .= "菜品ID: {$dish['id']}, 名称: {$dish['name']}, 制作步骤: {$dish['steps']}\n";
        }
        
        // 构造营养分类信息
        $nutritionInfo = "";
        foreach ($nutritions as $nutrition) {
            $nutritionInfo .= "营养分类ID: {$nutrition['id']}, 名称: {$nutrition['name']}\n";
        }
        
        // 构造提示词
        $prompt = "根据以下菜品信息和营养分类信息，为每个菜品匹配合适的营养分类，并生成相应的MySQL插入语句：\n\n";
        $prompt .= "菜品信息：\n{$dishInfo}\n";
        $prompt .= "营养分类信息：\n{$nutritionInfo}\n\n";
        $prompt .= "请严格按照以下JSON格式返回结果，不要包含其他内容：\n";
        $prompt .= "{\n";
        $prompt .= "  \"sql_statements\": [\n";
        $prompt .= "    \"INSERT INTO fa_food_nutritionrel (dish_id, nutrition_id, createtime, updatetime, weigh) VALUES (1, 5, 1234567890, 1234567890, 1);\",\n";
        $prompt .= "    \"INSERT INTO fa_food_nutritionrel (dish_id, nutrition_id, createtime, updatetime, weigh) VALUES (2, 3, 1234567890, 1234567890, 1);\"\n";
        $prompt .= "  ]\n";
        $prompt .= "}\n\n";
        $prompt .= "注意事项：\n";
        $prompt .= "1. 每个菜品可能匹配多个营养分类，请根据菜品的营养成分、食材特点和健康价值尽可能全面地匹配所有合适的营养分类\n";
        $prompt .= "2. 仔细分析菜品的食材组成和营养结构，确保不遗漏任何可能的营养分类\n";
        $prompt .= "3. 生成的SQL语句必须是INSERT INTO语句，操作的表名为fa_food_nutritionrel\n";
        $prompt .= "4. 字段包括：dish_id, nutrition_id, createtime, updatetime, weigh\n";
        $prompt .= "5. createtime和updatetime使用当前时间戳\n";
        $prompt .= "6. weigh字段默认为1\n";
        $prompt .= "7. 只返回标准JSON格式的数据，严格按照上面提供的JSON示例格式，不要包含任何其他说明文字、注释或额外内容，不要使用Markdown代码块标记";
        
        $data = [
            'model' => $model,
            'messages' => [
                [
                    'role' => 'user',
                    'content' => $prompt
                ]
            ],
            'temperature' => 0.1,
            'max_tokens' => 30000
        ];
        
        // 发起HTTP请求
        $headers = [
            'Authorization: Bearer ' . $apiKey,
            'Content-Type: application/json'
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 1130);
        
        $response = curl_exec($ch);
        
        if (curl_errno($ch)) {
            \think\Log::error('千问API调用错误: ' . curl_error($ch));
            curl_close($ch);
            return [];
        }
        
        curl_close($ch);
        
        // 打印API返回的原始内容用于调试
        \think\Log::info('千问API返回的原始内容: ' . $response);
        dump('千问API返回的原始内容: ' . $response);
        
        $responseArr = json_decode($response, true);
        if (empty($responseArr['choices'][0]['message']['content'])) {
            \think\Log::error('千问API返回内容为空或格式不正确');
            dump('千问API返回内容为空或格式不正确');
            return [];
        }
        
        // 解析返回的JSON内容
        $content = trim($responseArr['choices'][0]['message']['content']);
        
        // 打印解析后的content内容用于调试
        \think\Log::info('千问API返回的content内容: ' . $content);
        dump('千问API返回的content内容: ' . $content);
        
        // 尝试提取JSON部分
        if (preg_match('/\{.*\}/s', $content, $matches)) {
            $jsonStr = $matches[0];
            // 打印提取的JSON字符串用于调试
            \think\Log::info('提取的JSON字符串: ' . $jsonStr);
            dump('提取的JSON字符串: ' . $jsonStr);
            
            $result = json_decode($jsonStr, true);
            if (json_last_error() === JSON_ERROR_NONE && isset($result['sql_statements'])) {
                return $result['sql_statements'];
            } else {
                \think\Log::error('JSON解析失败或缺少sql_statements字段: ' . json_last_error_msg());
                dump('JSON解析失败或缺少sql_statements字段: ' . json_last_error_msg());
            }
        } else {
            \think\Log::error('未能从返回内容中提取JSON格式数据');
            dump('未能从返回内容中提取JSON格式数据');
        }
        
        return [];
    }
    
    /**
     * 调用千问API生成菜品与时段分类的关联语句
     * @param array $dishes 菜品数据
     * @param array $periods 时段分类数据
     * @return array SQL语句数组
     */
    private function generatePeriodRelationsByQwen($dishes, $periods) {
        // 阿里云千问API配置
        $apiKey = 'sk-416b931b781c420c9f6331b7346962b5';
        $apiUrl = 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions';
        $model = 'qwen-plus';
        
        // 构造菜品信息
        $dishInfo = "";
        foreach ($dishes as $dish) {
            $dishInfo .= "菜品ID: {$dish['id']}, 名称: {$dish['name']}, 制作步骤: {$dish['steps']}\n";
        }
        
        // 构造时段分类信息
        $periodInfo = "";
        foreach ($periods as $period) {
            $periodInfo .= "时段分类ID: {$period['id']}, 名称: {$period['name']}\n";
        }
        
        // 构造提示词
        $prompt = "根据以下菜品信息和时段分类信息，为每个菜品匹配合适的时段分类，并生成相应的MySQL插入语句：\n\n";
        $prompt .= "菜品信息：\n{$dishInfo}\n";
        $prompt .= "时段分类信息：\n{$periodInfo}\n\n";
        $prompt .= "请严格按照以下JSON格式返回结果，不要包含其他内容：\n";
        $prompt .= "{\n";
        $prompt .= "  \"sql_statements\": [\n";
        $prompt .= "    \"INSERT INTO fa_food_periodrel (dish_id, period_id, createtime, updatetime, weigh) VALUES (1, 5, 1234567890, 1234567890, 1);\",\n";
        $prompt .= "    \"INSERT INTO fa_food_periodrel (dish_id, period_id, createtime, updatetime, weigh) VALUES (2, 3, 1234567890, 1234567890, 1);\"\n";
        $prompt .= "  ]\n";
        $prompt .= "}\n\n";
        $prompt .= "注意事项：\n";
        $prompt .= "1. 每个菜品可能匹配多个时段分类，请根据菜品的食用时间、制作特点和消费场景尽可能全面地匹配所有合适的时段分类\n";
        $prompt .= "2. 仔细分析菜品的特点和适用场景，确保不遗漏任何可能的时段分类\n";
        $prompt .= "3. 生成的SQL语句必须是INSERT INTO语句，操作的表名为fa_food_periodrel\n";
        $prompt .= "4. 字段包括：dish_id, period_id, createtime, updatetime, weigh\n";
        $prompt .= "5. createtime和updatetime使用当前时间戳\n";
        $prompt .= "6. weigh字段默认为1\n";
        $prompt .= "7. 只返回标准JSON格式的数据，严格按照上面提供的JSON示例格式，不要包含任何其他说明文字、注释或额外内容，不要使用Markdown代码块标记";
        
        $data = [
            'model' => $model,
            'messages' => [
                [
                    'role' => 'user',
                    'content' => $prompt
                ]
            ],
            'temperature' => 0.1,
            'max_tokens' => 30000
        ];
        
        // 发起HTTP请求
        $headers = [
            'Authorization: Bearer ' . $apiKey,
            'Content-Type: application/json'
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 1130);
        
        $response = curl_exec($ch);
        
        if (curl_errno($ch)) {
            \think\Log::error('千问API调用错误: ' . curl_error($ch));
            curl_close($ch);
            return [];
        }
        
        curl_close($ch);
        
        // 打印API返回的原始内容用于调试
        \think\Log::info('千问API返回的原始内容: ' . $response);
        dump('千问API返回的原始内容: ' . $response);
        
        $responseArr = json_decode($response, true);
        if (empty($responseArr['choices'][0]['message']['content'])) {
            \think\Log::error('千问API返回内容为空或格式不正确');
            dump('千问API返回内容为空或格式不正确');
            return [];
        }
        
        // 解析返回的JSON内容
        $content = trim($responseArr['choices'][0]['message']['content']);
        
        // 打印解析后的content内容用于调试
        \think\Log::info('千问API返回的content内容: ' . $content);
        dump('千问API返回的content内容: ' . $content);
        
        // 尝试提取JSON部分
        if (preg_match('/\{.*\}/s', $content, $matches)) {
            $jsonStr = $matches[0];
            // 打印提取的JSON字符串用于调试
            \think\Log::info('提取的JSON字符串: ' . $jsonStr);
            dump('提取的JSON字符串: ' . $jsonStr);
            
            $result = json_decode($jsonStr, true);
            if (json_last_error() === JSON_ERROR_NONE && isset($result['sql_statements'])) {
                return $result['sql_statements'];
            } else {
                \think\Log::error('JSON解析失败或缺少sql_statements字段: ' . json_last_error_msg());
                dump('JSON解析失败或缺少sql_statements字段: ' . json_last_error_msg());
            }
        } else {
            \think\Log::error('未能从返回内容中提取JSON格式数据');
            dump('未能从返回内容中提取JSON格式数据');
        }
        
        return [];
    }
    
    /**
     * 调用千问API生成菜品与地域分类的关联语句
     * @param array $dishes 菜品数据
     * @param array $regions 地域分类数据
     * @return array SQL语句数组
     */
    private function generateRegionRelationsByQwen($dishes, $regions) {
        // 阿里云千问API配置
        $apiKey = 'sk-416b931b781c420c9f6331b7346962b5';
        $apiUrl = 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions';
        $model = 'qwen-plus';
        
        // 构造菜品信息
        $dishInfo = "";
        foreach ($dishes as $dish) {
            $dishInfo .= "菜品ID: {$dish['id']}, 名称: {$dish['name']}, 制作步骤: {$dish['steps']}\n";
        }
        
        // 构造地域分类信息
        $regionInfo = "";
        foreach ($regions as $region) {
            $regionInfo .= "地域分类ID: {$region['id']}, 名称: {$region['name']}\n";
        }
        
        // 构造提示词
        $prompt = "根据以下菜品信息和地域分类信息，为每个菜品匹配合适的地域分类，并生成相应的MySQL插入语句：\n\n";
        $prompt .= "菜品信息：\n{$dishInfo}\n";
        $prompt .= "地域分类信息：\n{$regionInfo}\n\n";
        $prompt .= "请严格按照以下JSON格式返回结果，不要包含其他内容：\n";
        $prompt .= "{\n";
        $prompt .= "  \"sql_statements\": [\n";
        $prompt .= "    \"INSERT INTO fa_food_regionrel (dish_id, region_id, createtime, updatetime, weigh) VALUES (1, 5, 1234567890, 1234567890, 1);\",\n";
        $prompt .= "    \"INSERT INTO fa_food_regionrel (dish_id, region_id, createtime, updatetime, weigh) VALUES (2, 3, 1234567890, 1234567890, 1);\"\n";
        $prompt .= "  ]\n";
        $prompt .= "}\n\n";
        $prompt .= "注意事项：\n";
        $prompt .= "1. 每个菜品可能匹配多个地域分类，请根据菜品的地域特色、食材来源和风味特点尽可能全面地匹配所有合适的地域分类\n";
        $prompt .= "2. 仔细分析菜品的地域特征，确保不遗漏任何可能的地域分类\n";
        $prompt .= "3. 生成的SQL语句必须是INSERT INTO语句，操作的表名为fa_food_regionrel\n";
        $prompt .= "4. 字段包括：dish_id, region_id, createtime, updatetime, weigh\n";
        $prompt .= "5. createtime和updatetime使用当前时间戳\n";
        $prompt .= "6. weigh字段默认为1\n";
        $prompt .= "7. 只返回标准JSON格式的数据，严格按照上面提供的JSON示例格式，不要包含任何其他说明文字、注释或额外内容，不要使用Markdown代码块标记";
        
        $data = [
            'model' => $model,
            'messages' => [
                [
                    'role' => 'user',
                    'content' => $prompt
                ]
            ],
            'temperature' => 0.1,
            'max_tokens' => 30000
        ];
        
        // 发起HTTP请求
        $headers = [
            'Authorization: Bearer ' . $apiKey,
            'Content-Type: application/json'
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 1130);
        
        $response = curl_exec($ch);
        
        if (curl_errno($ch)) {
            \think\Log::error('千问API调用错误: ' . curl_error($ch));
            curl_close($ch);
            return [];
        }
        
        curl_close($ch);
        
        // 打印API返回的原始内容用于调试
        \think\Log::info('千问API返回的原始内容: ' . $response);
        dump('千问API返回的原始内容: ' . $response);
        
        $responseArr = json_decode($response, true);
        if (empty($responseArr['choices'][0]['message']['content'])) {
            \think\Log::error('千问API返回内容为空或格式不正确');
            dump('千问API返回内容为空或格式不正确');
            return [];
        }
        
        // 解析返回的JSON内容
        $content = trim($responseArr['choices'][0]['message']['content']);
        
        // 打印解析后的content内容用于调试
        \think\Log::info('千问API返回的content内容: ' . $content);
        dump('千问API返回的content内容: ' . $content);
        
        // 尝试提取JSON部分
        if (preg_match('/\{.*\}/s', $content, $matches)) {
            $jsonStr = $matches[0];
            // 打印提取的JSON字符串用于调试
            \think\Log::info('提取的JSON字符串: ' . $jsonStr);
            dump('提取的JSON字符串: ' . $jsonStr);
            
            $result = json_decode($jsonStr, true);
            if (json_last_error() === JSON_ERROR_NONE && isset($result['sql_statements'])) {
                return $result['sql_statements'];
            } else {
                \think\Log::error('JSON解析失败或缺少sql_statements字段: ' . json_last_error_msg());
                dump('JSON解析失败或缺少sql_statements字段: ' . json_last_error_msg());
            }
        } else {
            \think\Log::error('未能从返回内容中提取JSON格式数据');
            dump('未能从返回内容中提取JSON格式数据');
        }
        
        return [];
    }
    
    /**
     * 调用千问API生成菜品与场景分类的关联语句
     * @param array $dishes 菜品数据
     * @param array $scenes 场景分类数据
     * @return array SQL语句数组
     */
    private function generateSceneRelationsByQwen($dishes, $scenes) {
        // 阿里云千问API配置
        $apiKey = 'sk-416b931b781c420c9f6331b7346962b5';
        $apiUrl = 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions';
        $model = 'qwen-plus';
        
        // 构造菜品信息
        $dishInfo = "";
        foreach ($dishes as $dish) {
            $dishInfo .= "菜品ID: {$dish['id']}, 名称: {$dish['name']}, 制作步骤: {$dish['steps']}\n";
        }
        
        // 构造场景分类信息
        $sceneInfo = "";
        foreach ($scenes as $scene) {
            $sceneInfo .= "场景分类ID: {$scene['id']}, 名称: {$scene['name']}\n";
        }
        
        // 构造提示词
        $prompt = "根据以下菜品信息和场景分类信息，为每个菜品匹配合适的场景分类，并生成相应的MySQL插入语句：\n\n";
        $prompt .= "菜品信息：\n{$dishInfo}\n";
        $prompt .= "场景分类信息：\n{$sceneInfo}\n\n";
        $prompt .= "请严格按照以下JSON格式返回结果，不要包含其他内容：\n";
        $prompt .= "{\n";
        $prompt .= "  \"sql_statements\": [\n";
        $prompt .= "    \"INSERT INTO fa_food_scenerel (dish_id, scene_id, createtime, updatetime, weigh) VALUES (1, 5, 1234567890, 1234567890, 1);\",\n";
        $prompt .= "    \"INSERT INTO fa_food_scenerel (dish_id, scene_id, createtime, updatetime, weigh) VALUES (2, 3, 1234567890, 1234567890, 1);\"\n";
        $prompt .= "  ]\n";
        $prompt .= "}\n\n";
        $prompt .= "注意事项：\n";
        $prompt .= "1. 每个菜品可能匹配多个场景分类，请根据菜品的适用场合、消费场景和文化背景尽可能全面地匹配所有合适的场景分类\n";
        $prompt .= "2. 仔细分析菜品的特点和适用场景，确保不遗漏任何可能的场景分类\n";
        $prompt .= "3. 生成的SQL语句必须是INSERT INTO语句，操作的表名为fa_food_scenerel\n";
        $prompt .= "4. 字段包括：dish_id, scene_id, createtime, updatetime, weigh\n";
        $prompt .= "5. createtime和updatetime使用当前时间戳\n";
        $prompt .= "6. weigh字段默认为1\n";
        $prompt .= "7. 只返回标准JSON格式的数据，严格按照上面提供的JSON示例格式，不要包含任何其他说明文字、注释或额外内容，不要使用Markdown代码块标记";
        
        $data = [
            'model' => $model,
            'messages' => [
                [
                    'role' => 'user',
                    'content' => $prompt
                ]
            ],
            'temperature' => 0.1,
            'max_tokens' => 30000
        ];
        
        // 发起HTTP请求
        $headers = [
            'Authorization: Bearer ' . $apiKey,
            'Content-Type: application/json'
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 1130);
        
        $response = curl_exec($ch);
        
        if (curl_errno($ch)) {
            \think\Log::error('千问API调用错误: ' . curl_error($ch));
            curl_close($ch);
            return [];
        }
        
        curl_close($ch);
        
        // 打印API返回的原始内容用于调试
        \think\Log::info('千问API返回的原始内容: ' . $response);
        dump('千问API返回的原始内容: ' . $response);
        
        $responseArr = json_decode($response, true);
        if (empty($responseArr['choices'][0]['message']['content'])) {
            \think\Log::error('千问API返回内容为空或格式不正确');
            dump('千问API返回内容为空或格式不正确');
            return [];
        }
        
        // 解析返回的JSON内容
        $content = trim($responseArr['choices'][0]['message']['content']);
        
        // 打印解析后的content内容用于调试
        \think\Log::info('千问API返回的content内容: ' . $content);
        dump('千问API返回的content内容: ' . $content);
        
        // 尝试提取JSON部分
        if (preg_match('/\{.*\}/s', $content, $matches)) {
            $jsonStr = $matches[0];
            // 打印提取的JSON字符串用于调试
            \think\Log::info('提取的JSON字符串: ' . $jsonStr);
            dump('提取的JSON字符串: ' . $jsonStr);
            
            $result = json_decode($jsonStr, true);
            if (json_last_error() === JSON_ERROR_NONE && isset($result['sql_statements'])) {
                return $result['sql_statements'];
            } else {
                \think\Log::error('JSON解析失败或缺少sql_statements字段: ' . json_last_error_msg());
                dump('JSON解析失败或缺少sql_statements字段: ' . json_last_error_msg());
            }
        } else {
            \think\Log::error('未能从返回内容中提取JSON格式数据');
            dump('未能从返回内容中提取JSON格式数据');
        }
        
        return [];
    }

        /**
     * 调用千问API生成菜品与工艺分类的关联语句
     * @param array $dishes 菜品数据
     * @param array $techs 工艺分类数据
     * @return array SQL语句数组
     */
    private function generateTechRelationsByQwen($dishes, $techs) {
        // 阿里云千问API配置
        $apiKey = 'sk-416b931b781c420c9f6331b7346962b5';
        $apiUrl = 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions';
        $model = 'qwen-plus';
        
        // 构造菜品信息
        $dishInfo = "";
        foreach ($dishes as $dish) {
            $dishInfo .= "菜品ID: {$dish['id']}, 名称: {$dish['name']}, 制作步骤: {$dish['steps']}\n";
        }
        
        // 构造工艺分类信息
        $techInfo = "";
        foreach ($techs as $tech) {
            $techInfo .= "工艺分类ID: {$tech['id']}, 名称: {$tech['name']}\n";
        }
        
        // 构造提示词
        $prompt = "根据以下菜品信息和工艺分类信息，为每个菜品匹配合适的工艺分类，并生成相应的MySQL插入语句：\n\n";
        $prompt .= "菜品信息：\n{$dishInfo}\n";
        $prompt .= "工艺分类信息：\n{$techInfo}\n\n";
        $prompt .= "请严格按照以下JSON格式返回结果，不要包含其他内容：\n";
        $prompt .= "{\n";
        $prompt .= "  \"sql_statements\": [\n";
        $prompt .= "    \"INSERT INTO fa_food_techrel (dish_id, tech_id, createtime, updatetime, weigh) VALUES (1, 5, 1234567890, 1234567890, 1);\",\n";
        $prompt .= "    \"INSERT INTO fa_food_techrel (dish_id, tech_id, createtime, updatetime, weigh) VALUES (2, 3, 1234567890, 1234567890, 1);\"\n";
        $prompt .= "  ]\n";
        $prompt .= "}\n\n";
        $prompt .= "注意事项：\n";
        $prompt .= "1. 每个菜品可能匹配多个工艺分类，请根据菜品的烹饪技法、制作工艺和加工方式尽可能全面地匹配所有合适的工艺分类\n";
        $prompt .= "2. 仔细分析菜品的制作步骤和烹饪方法，确保不遗漏任何可能的工艺分类\n";
        $prompt .= "3. 生成的SQL语句必须是INSERT INTO语句，操作的表名为fa_food_techrel\n";
        $prompt .= "4. 字段包括：dish_id, tech_id, createtime, updatetime, weigh\n";
        $prompt .= "5. createtime和updatetime使用当前时间戳\n";
        $prompt .= "6. weigh字段默认为1\n";
        $prompt .= "7. 只返回标准JSON格式的数据，严格按照上面提供的JSON示例格式，不要包含任何其他说明文字、注释或额外内容，不要使用Markdown代码块标记";
        
        $data = [
            'model' => $model,
            'messages' => [
                [
                    'role' => 'user',
                    'content' => $prompt
                ]
            ],
            'temperature' => 0.1,
            'max_tokens' => 30000
        ];
        
        // 发起HTTP请求
        $headers = [
            'Authorization: Bearer ' . $apiKey,
            'Content-Type: application/json'
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 1130);
        
        $response = curl_exec($ch);
        
        if (curl_errno($ch)) {
            \think\Log::error('千问API调用错误: ' . curl_error($ch));
            curl_close($ch);
            return [];
        }
        
        curl_close($ch);
        
        // 打印API返回的原始内容用于调试
        \think\Log::info('千问API返回的原始内容: ' . $response);
        dump('千问API返回的原始内容: ' . $response);
        
        $responseArr = json_decode($response, true);
        if (empty($responseArr['choices'][0]['message']['content'])) {
            \think\Log::error('千问API返回内容为空或格式不正确');
            dump('千问API返回内容为空或格式不正确');
            return [];
        }
        
        // 解析返回的JSON内容
        $content = trim($responseArr['choices'][0]['message']['content']);
        
        // 打印解析后的content内容用于调试
        \think\Log::info('千问API返回的content内容: ' . $content);
        dump('千问API返回的content内容: ' . $content);
        
        // 尝试提取JSON部分
        if (preg_match('/\{.*\}/s', $content, $matches)) {
            $jsonStr = $matches[0];
            // 打印提取的JSON字符串用于调试
            \think\Log::info('提取的JSON字符串: ' . $jsonStr);
            dump('提取的JSON字符串: ' . $jsonStr);
            
            $result = json_decode($jsonStr, true);
            if (json_last_error() === JSON_ERROR_NONE && isset($result['sql_statements'])) {
                return $result['sql_statements'];
            } else {
                \think\Log::error('JSON解析失败或缺少sql_statements字段: ' . json_last_error_msg());
                dump('JSON解析失败或缺少sql_statements字段: ' . json_last_error_msg());
            }
        } else {
            \think\Log::error('未能从返回内容中提取JSON格式数据');
            dump('未能从返回内容中提取JSON格式数据');
        }
        
        return [];
    }
    
    /**
     * 为菜品设置形态分类标签（调用阿里云千问API）
     * 数据库操作：
     * 1. 查询food_dish表中ai_called=1的菜品记录
     * 2. 查询food_form表中status=1的形态分类数据
     * 3. 调用千问API生成菜品与形态分类的关联SQL语句
     * 4. 执行生成的INSERT语句，将关联数据插入fa_food_formrel表
     * 5. 更新food_dish表中相关菜品的ai_called字段为2，表示已完成形态分类处理
     * @ApiMethod (GET)
     * @ApiTitle (为菜品设置形态分类标签)
     * @ApiSummary (调用阿里云千问API为菜品设置形态分类标签)
     * @ApiReturn ({ "code": 1, "msg": "处理完成，成功1条，失败0条", "data": { "success_count": 1, "fail_list": [] } })
     */
    public function setFoodLabel() {
        // 查询已处理的菜品（ai_called = 1）
        $dishes = Db::name('food_dish')
                ->where('ai_called', 1)
                ->field('id, name, steps')
                ->limit(10)
                ->select();
        
        if (empty($dishes)) {
            return json(['code' => 0, 'msg' => '没有需要处理的菜品']);
        }
        
        // 获取菜品形态分类数据
        $forms = Db::name('food_form')
                ->where('status', 1)
                ->field('id, name')
                ->select();
        
        if (empty($forms)) {
            return json(['code' => 0, 'msg' => '没有可用的菜品形态分类']);
        }
        
        // 调用千问API生成关联语句
        $sqlStatements = $this->generateFormRelationsByQwen($dishes, $forms);
        if (empty($sqlStatements)) {
            return json(['code' => 0, 'msg' => '生成SQL语句失败']);
        }
        
        // 执行生成的SQL语句
        $successCount = 0;
        foreach ($sqlStatements as $sql) {
            try {
                Db::execute($sql);
                $successCount++;
            } catch (\Exception $e) {
                \think\Log::error('执行SQL语句失败: ' . $e->getMessage() . ' SQL: ' . $sql);
            }
        }
        
        // 将处理过的菜品的ai_called字段更新为2，表示已完成形态分类处理
        $dishIds = array_column($dishes, 'id');
        Db::name('food_dish')
            ->where('id', 'in', $dishIds)
            ->update(['ai_called' => 2, 'updatetime' => time()]);
        
        return json(['code' => 1, 'msg' => '处理完成，成功' . $successCount . '条']);
    }
    
    /**
     * 为菜品设置人群分类标签（调用阿里云千问API）
     * 数据库操作：
     * 1. 查询food_dish表中ai_crowd<>1的菜品记录
     * 2. 查询food_crowd表中status=1的人群分类数据
     * 3. 调用千问API生成菜品与人群分类的关联SQL语句
     * 4. 执行生成的INSERT语句，将关联数据插入fa_food_crowdrel表
     * 5. 更新food_dish表中相关菜品的ai_crowd字段为1，表示已完成人群分类处理
     * @ApiMethod (GET)
     * @ApiTitle (为菜品设置人群分类标签)
     * @ApiSummary (调用阿里云千问API为菜品设置人群分类标签)
     * @ApiReturn ({ "code": 1, "msg": "处理完成，成功1条，失败0条", "data": { "success_count": 1, "fail_list": [] } })
     */
    public function setFoodcrowd() { 
        // 查询已处理的菜品（ai_called = 1）
        $dishes = Db::name('food_dish')
                ->where('ai_crowd','<>', 1)
                ->field('id, name, steps')
                ->limit(10)
                ->select();
        if (empty($dishes)) {
            return json(['code' => 0, 'msg' => '没有需要处理的菜品']);
        }
        
        // 获取菜品人群分类数据
        $crowds = Db::name('food_crowd')
                ->where('status', 1)
                ->field('id, name')
                ->select();
        
        if (empty($crowds)) {
            return json(['code' => 0, 'msg' => '没有可用的菜品人群分类']);
        }
        
        // 调用千问API生成关联语句
        $sqlStatements = $this->generateCrowdRelationsByQwen($dishes, $crowds);
        if (empty($sqlStatements)) {
            return json(['code' => 0, 'msg' => '生成SQL语句失败']);
        }
        
        // 执行生成的SQL语句
        $successCount = 0;
        foreach ($sqlStatements as $sql) {
            try {
                Db::execute($sql);
                $successCount++;
            } catch (\Exception $e) {
                \think\Log::error('执行SQL语句失败: ' . $e->getMessage() . ' SQL: ' . $sql);
            }
        }
        
        // 将处理过的菜品的ai_called字段更新为2，表示已完成人群分类处理
        $dishIds = array_column($dishes, 'id');
        Db::name('food_dish')
            ->where('id', 'in', $dishIds)
            ->update(['ai_crowd' => 1, 'updatetime' => time()]);
        
        return json(['code' => 1, 'msg' => '处理完成，成功' . $successCount . '条']);
    }

    /**
     * 为菜品设置菜系分类标签（调用阿里云千问API）
     * 数据库操作：
     * 1. 查询food_dish表中ai_cuisine<>1的菜品记录
     * 2. 查询food_cuisine表中status=1的菜系分类数据
     * 3. 调用千问API生成菜品与菜系分类的关联SQL语句
     * 4. 执行生成的INSERT语句，将关联数据插入fa_food_cuisinerel表
     * 5. 更新food_dish表中相关菜品的ai_cuisine字段为1，表示已完成菜系分类处理
     * @ApiMethod (GET)
     * @ApiTitle (为菜品设置菜系分类标签)
     * @ApiSummary (调用阿里云千问API为菜品设置菜系分类标签)
     * @ApiReturn ({ "code": 1, "msg": "处理完成，成功1条，失败0条", "data": { "success_count": 1, "fail_list": [] } })
     */
    public function setFoodcuisine() {
        // 查询已处理的菜品（ai_called = 1）
        $dishes = Db::name('food_dish')
                ->where('ai_cuisine','<>', 1)
                ->field('id, name, steps')
                ->limit(10)
                ->select();
        
        if (empty($dishes)) {
            return json(['code' => 0, 'msg' => '没有需要处理的菜品']);
        }
        
        // 获取菜系分类数据
        $cuisines = Db::name('food_cuisine')
                ->where('status', 1)
                ->field('id, name')
                ->select();
        
        if (empty($cuisines)) {
            return json(['code' => 0, 'msg' => '没有可用的菜系分类']);
        }
        
        // 调用千问API生成关联语句
        $sqlStatements = $this->generateCuisineRelationsByQwen($dishes, $cuisines);
        if (empty($sqlStatements)) {
            return json(['code' => 0, 'msg' => '生成SQL语句失败']);
        }
        
        // 执行生成的SQL语句
        $successCount = 0;
        foreach ($sqlStatements as $sql) {
            try {
                Db::execute($sql);
                $successCount++;
            } catch (\Exception $e) {
                \think\Log::error('执行SQL语句失败: ' . $e->getMessage() . ' SQL: ' . $sql);
            }
        }
        
        // 将处理过的菜品的ai_called字段更新为2，表示已完成菜系分类处理
        $dishIds = array_column($dishes, 'id');
        Db::name('food_dish')
            ->where('id', 'in', $dishIds)
            ->update(['ai_cuisine' => 1, 'updatetime' => time()]);
        
        return json(['code' => 1, 'msg' => '处理完成，成功' . $successCount . '条']);
    }

    /**
     * 为菜品设置营养分类标签（调用阿里云千问API）
     * 数据库操作：
     * 1. 查询food_dish表中ai_nutrition<>1的菜品记录
     * 2. 查询food_nutrition表中status=1的营养分类数据
     * 3. 调用千问API生成菜品与营养分类的关联SQL语句
     * 4. 执行生成的INSERT语句，将关联数据插入fa_food_nutritionrel表
     * 5. 更新food_dish表中相关菜品的ai_nutrition字段为1，表示已完成营养分类处理
     * @ApiMethod (GET)
     * @ApiTitle (为菜品设置营养分类标签)
     * @ApiSummary (调用阿里云千问API为菜品设置营养分类标签)
     * @ApiReturn ({ "code": 1, "msg": "处理完成，成功1条，失败0条", "data": { "success_count": 1, "fail_list": [] } })
     */
    public function setFoodnutrition() { 
        // 查询已处理的菜品（ai_called = 1）
        $dishes = Db::name('food_dish')
                ->where('ai_nutrition','<>', 1)
                ->field('id, name, steps')
                ->limit(10)
                ->select();
        
        if (empty($dishes)) {
            return json(['code' => 0, 'msg' => '没有需要处理的菜品']);
        }
        
        // 获取营养分类数据
        $nutritions = Db::name('food_nutrition')
                ->where('status', 1)
                ->field('id, name')
                ->select();
        
        if (empty($nutritions)) {
            return json(['code' => 0, 'msg' => '没有可用的营养分类']);
        }
        
        // 调用千问API生成关联语句
        $sqlStatements = $this->generateNutritionRelationsByQwen($dishes, $nutritions);
        if (empty($sqlStatements)) {
            return json(['code' => 0, 'msg' => '生成SQL语句失败']);
        }
        
        // 执行生成的SQL语句
        $successCount = 0;
        foreach ($sqlStatements as $sql) {
            try {
                Db::execute($sql);
                $successCount++;
            } catch (\Exception $e) {
                \think\Log::error('执行SQL语句失败: ' . $e->getMessage() . ' SQL: ' . $sql);
            }
        }
        
        // 将处理过的菜品的ai_called字段更新为2，表示已完成营养分类处理
        $dishIds = array_column($dishes, 'id');
        Db::name('food_dish')
            ->where('id', 'in', $dishIds)
            ->update(['ai_nutrition' => 1, 'updatetime' => time()]);
        
        return json(['code' => 1, 'msg' => '处理完成，成功' . $successCount . '条']);
    }
    
    /**
     * 为菜品设置时段分类标签（调用阿里云千问API）
     * 数据库操作：
     * 1. 查询food_dish表中ai_period<>1的菜品记录
     * 2. 查询food_period表中status=1的时段分类数据
     * 3. 调用千问API生成菜品与时段分类的关联SQL语句
     * 4. 执行生成的INSERT语句，将关联数据插入fa_food_periodrel表
     * 5. 更新food_dish表中相关菜品的ai_period字段为1，表示已完成时段分类处理
     * @ApiMethod (GET)
     * @ApiTitle (为菜品设置时段分类标签)
     * @ApiSummary (调用阿里云千问API为菜品设置时段分类标签)
     * @ApiReturn ({ "code": 1, "msg": "处理完成，成功1条，失败0条", "data": { "success_count": 1, "fail_list": [] } })
     */
    public function setFoodperiod() { 
        // 查询已处理的菜品（ai_called = 1）
        $dishes = Db::name('food_dish')
                ->where('ai_period','<>', 1)
                ->field('id, name, steps')
                ->limit(10)
                ->select();
        
        if (empty($dishes)) {
            return json(['code' => 0, 'msg' => '没有需要处理的菜品']);
        }
        
        // 获取时段分类数据
        $periods = Db::name('food_period')
                ->where('status', 1)
                ->field('id, name')
                ->select();
        
        if (empty($periods)) {
            return json(['code' => 0, 'msg' => '没有可用的时段分类']);
        }
        
        // 调用千问API生成关联语句
        $sqlStatements = $this->generatePeriodRelationsByQwen($dishes, $periods);
        if (empty($sqlStatements)) {
            return json(['code' => 0, 'msg' => '生成SQL语句失败']);
        }
        
        // 执行生成的SQL语句
        $successCount = 0;
        foreach ($sqlStatements as $sql) {
            try {
                Db::execute($sql);
                $successCount++;
            } catch (\Exception $e) {
                \think\Log::error('执行SQL语句失败: ' . $e->getMessage() . ' SQL: ' . $sql);
            }
        }
        
        // 将处理过的菜品的ai_called字段更新为2，表示已完成时段分类处理
        $dishIds = array_column($dishes, 'id');
        Db::name('food_dish')
            ->where('id', 'in', $dishIds)
            ->update(['ai_period' => 1, 'updatetime' => time()]);
        
        return json(['code' => 1, 'msg' => '处理完成，成功' . $successCount . '条']);
    }
    
    /**
     * 为菜品设置地域分类标签（调用阿里云千问API）
     * 数据库操作：
     * 1. 查询food_dish表中ai_region<>1的菜品记录
     * 2. 查询food_region表中status=1的地域分类数据
     * 3. 调用千问API生成菜品与地域分类的关联SQL语句
     * 4. 执行生成的INSERT语句，将关联数据插入fa_food_regionrel表
     * 5. 更新food_dish表中相关菜品的ai_region字段为1，表示已完成地域分类处理
     * @ApiMethod (GET)
     * @ApiTitle (为菜品设置地域分类标签)
     * @ApiSummary (调用阿里云千问API为菜品设置地域分类标签)
     * @ApiReturn ({ "code": 1, "msg": "处理完成，成功1条，失败0条", "data": { "success_count": 1, "fail_list": [] } })
     */
    public function setFoodregion() { 
        // 查询已处理的菜品（ai_called = 1）
        $dishes = Db::name('food_dish')
                ->where('ai_region','<>', 1)
                ->field('id, name, steps')
                ->limit(10)
                ->select();
        
        if (empty($dishes)) {
            return json(['code' => 0, 'msg' => '没有需要处理的菜品']);
        }
        
        // 获取地域分类数据
        $regions = Db::name('food_region')
                ->where('status', 1)
                ->field('id, name')
                ->select();
        
        if (empty($regions)) {
            return json(['code' => 0, 'msg' => '没有可用的地域分类']);
        }
        
        // 调用千问API生成关联语句
        $sqlStatements = $this->generateRegionRelationsByQwen($dishes, $regions);
        if (empty($sqlStatements)) {
            return json(['code' => 0, 'msg' => '生成SQL语句失败']);
        }
        
        // 执行生成的SQL语句
        $successCount = 0;
        foreach ($sqlStatements as $sql) {
            try {
                Db::execute($sql);
                $successCount++;
            } catch (\Exception $e) {
                \think\Log::error('执行SQL语句失败: ' . $e->getMessage() . ' SQL: ' . $sql);
            }
        }
        
        // 将处理过的菜品的ai_called字段更新为2，表示已完成地域分类处理
        $dishIds = array_column($dishes, 'id');
        Db::name('food_dish')
            ->where('id', 'in', $dishIds)
            ->update(['ai_region' => 1, 'updatetime' => time()]);
        
        return json(['code' => 1, 'msg' => '处理完成，成功' . $successCount . '条']);
    }
    
    /**
     * 为菜品设置场景分类标签（调用阿里云千问API）
     * 数据库操作：
     * 1. 查询food_dish表中ai_scene<>1的菜品记录
     * 2. 查询food_scene表中status=1的场景分类数据
     * 3. 调用千问API生成菜品与场景分类的关联SQL语句
     * 4. 执行生成的INSERT语句，将关联数据插入fa_food_scenerel表
     * 5. 更新food_dish表中相关菜品的ai_scene字段为1，表示已完成场景分类处理
     * @ApiMethod (GET)
     * @ApiTitle (为菜品设置场景分类标签)
     * @ApiSummary (调用阿里云千问API为菜品设置场景分类标签)
     * @ApiReturn ({ "code": 1, "msg": "处理完成，成功1条，失败0条", "data": { "success_count": 1, "fail_list": [] } })
     */
    public function setFoodscene() { 
        // 查询已处理的菜品（ai_called = 1）
        $dishes = Db::name('food_dish')
                ->where('ai_scene','<>', 1)
                ->field('id, name, steps')
                ->limit(10)
                ->select();
        
        if (empty($dishes)) {
            return json(['code' => 0, 'msg' => '没有需要处理的菜品']);
        }
        
        // 获取场景分类数据
        $scenes = Db::name('food_scene')
                ->where('status', 1)
                ->field('id, name')
                ->select();
        
        if (empty($scenes)) {
            return json(['code' => 0, 'msg' => '没有可用的场景分类']);
        }
        
        // 调用千问API生成关联语句
        $sqlStatements = $this->generateSceneRelationsByQwen($dishes, $scenes);
        if (empty($sqlStatements)) {
            return json(['code' => 0, 'msg' => '生成SQL语句失败']);
        }
        
        // 执行生成的SQL语句
        $successCount = 0;
        foreach ($sqlStatements as $sql) {
            try {
                Db::execute($sql);
                $successCount++;
            } catch (\Exception $e) {
                \think\Log::error('执行SQL语句失败: ' . $e->getMessage() . ' SQL: ' . $sql);
            }
        }
        
        // 将处理过的菜品的ai_called字段更新为2，表示已完成场景分类处理
        $dishIds = array_column($dishes, 'id');
        Db::name('food_dish')
            ->where('id', 'in', $dishIds)
            ->update(['ai_scene' => 1, 'updatetime' => time()]);
        
        return json(['code' => 1, 'msg' => '处理完成，成功' . $successCount . '条']);
    }
    
    /**
     * 为菜品设置工艺分类标签（调用阿里云千问API）
     * 数据库操作：
     * 1. 查询food_dish表中ai_tech<>1的菜品记录
     * 2. 查询food_tech表中status=1的工艺分类数据
     * 3. 调用千问API生成菜品与工艺分类的关联SQL语句
     * 4. 执行生成的INSERT语句，将关联数据插入fa_food_techrel表
     * 5. 更新food_dish表中相关菜品的ai_tech字段为1，表示已完成工艺分类处理
     * @ApiMethod (GET)
     * @ApiTitle (为菜品设置工艺分类标签)
     * @ApiSummary (调用阿里云千问API为菜品设置工艺分类标签)
     * @ApiReturn ({ "code": 1, "msg": "处理完成，成功1条，失败0条", "data": { "success_count": 1, "fail_list": [] } })
     */
    public function setFoodtech() { 
        // 查询已处理的菜品（ai_called = 1）
        $dishes = Db::name('food_dish')
                ->where('ai_tech','<>', 1)
                ->field('id, name, steps')
                ->limit(10)
                ->select();
        
        if (empty($dishes)) {
            return json(['code' => 0, 'msg' => '没有需要处理的菜品']);
        }
        
        // 获取工艺分类数据
        $techs = Db::name('food_tech')
                ->where('status', 1)
                ->field('id, name')
                ->select();
        
        if (empty($techs)) {
            return json(['code' => 0, 'msg' => '没有可用的工艺分类']);
        }
        
        // 调用千问API生成关联语句
        $sqlStatements = $this->generateTechRelationsByQwen($dishes, $techs);
        if (empty($sqlStatements)) {
            return json(['code' => 0, 'msg' => '生成SQL语句失败']);
        }
        
        // 执行生成的SQL语句
        $successCount = 0;
        foreach ($sqlStatements as $sql) {
            try {
                Db::execute($sql);
                $successCount++;
            } catch (\Exception $e) {
                \think\Log::error('执行SQL语句失败: ' . $e->getMessage() . ' SQL: ' . $sql);
            }
        }
        
        // 将处理过的菜品的ai_called字段更新为2，表示已完成工艺分类处理
        $dishIds = array_column($dishes, 'id');
        Db::name('food_dish')
            ->where('id', 'in', $dishIds)
            ->update(['ai_tech' => 1, 'updatetime' => time()]);
        
        return json(['code' => 1, 'msg' => '处理完成，成功' . $successCount . '条']);
    }


    /**
     * 自动为未分类食材补充分类（调用阿里云千问API）
     * @ApiMethod (GET)
     * @ApiTitle (自动分类食材)
     * @ApiSummary (为未分类食材自动分配分类)
     * @ApiReturn ({ "code": 1, "msg": "处理完成，成功1条，失败0条", "data": { "success_count": 1, "fail_list": [] } })
     */
    public function autoClassify()
    {
        // 直接调用admin控制器中的方法
        $adminController = new \app\admin\controller\food\Ingredient();
        // 由于autoClassify方法中没有使用$this->request，所以可以直接调用
        return $adminController->autoClassify();
    }
    
    /**
     * 批量获取菜品制作信息并更新数据库（调用阿里云千问API）
     * @ApiMethod (POST)
     * @ApiTitle (批量处理菜品制作信息)
     * @ApiSummary (批量获取未处理菜品所需食材列表、烹饪时长、制作步骤，并更新数据库)
     * @ApiReturn ({ "code": 1, "msg": "处理成功", "data": { "success_count": 5, "processed_dishes": [1, 2, 3] } })
     */
    public function batchGetDishInfo()
    {
        try {
            dump('开始执行batchGetDishInfo方法');
            trace('开始执行batchGetDishInfo方法', 'info');
            
            // 直接从数据库获取未处理的菜品（ai_called = 0），限制每次处理10个
            $dishes = Db::name('food_dish')
                ->where('ai_called', 0)
                ->field('id, name')
                ->limit(10)
                ->select();
                
            dump('查询到的菜品数据: ' . json_encode($dishes, JSON_UNESCAPED_UNICODE));
            trace('查询到的菜品数据: ' . json_encode($dishes, JSON_UNESCAPED_UNICODE), 'info');
                
            if (empty($dishes)) {
                dump('没有需要处理的菜品');
                trace('没有需要处理的菜品', 'info');
                // 检查是否在CLI模式下运行
                if (php_sapi_name() === 'cli') {
                    echo "没有需要处理的菜品\n";
                    return;
                }
                dump('没有需要处理的菜品');
            }
            
            dump('获取到未处理菜品数量: ' . count($dishes));
            trace('获取到未处理菜品数量: ' . count($dishes), 'info');
            
            // 调用阿里云千问API批量获取制作信息
            dump('开始调用千问API');
            trace('开始调用千问API', 'info');
            $result = $this->batchQueryDishInfoByQwen($dishes); // 传递完整的菜品数据
            dump('API返回结果: ' . json_encode($result, JSON_UNESCAPED_UNICODE));
            trace('API返回结果: ' . json_encode($result, JSON_UNESCAPED_UNICODE), 'info');
            
            if (empty($result)) {
                dump('获取菜品制作信息失败，API返回空结果');
                trace('获取菜品制作信息失败，API返回空结果', 'error');
                // 检查是否在CLI模式下运行
                if (php_sapi_name() === 'cli') {
                    echo "获取菜品制作信息失败\n";
                    return;
                }
                dump('获取菜品制作信息失败');
            }
            
            // 处理返回的数据，匹配食材ID
            dump('开始处理返回数据');
            trace('开始处理返回数据', 'info');
            $processedResult = $this->processBatchDishInfo($result, $dishes); // 传递完整的菜品数据
            dump('处理后的结果: ' . json_encode($processedResult, JSON_UNESCAPED_UNICODE));
            trace('处理后的结果: ' . json_encode($processedResult, JSON_UNESCAPED_UNICODE), 'info');
            
            if (empty($processedResult)) {
                dump('处理菜品信息失败，处理结果为空');
                trace('处理菜品信息失败，处理结果为空', 'error');
            }
            
            // 更新数据库
            dump('开始更新数据库');
            trace('开始更新数据库', 'info');
            $updateResult = $this->updateDishInfo($processedResult);
            dump('数据库更新结果: ' . json_encode($updateResult, JSON_UNESCAPED_UNICODE));
            trace('数据库更新结果: ' . json_encode($updateResult, JSON_UNESCAPED_UNICODE), 'info');
            
            // 检查是否在CLI模式下运行
            if (php_sapi_name() === 'cli') {
                echo "处理成功: " . json_encode($updateResult, JSON_UNESCAPED_UNICODE) . "\n";
                return;
            }
            dump(['处理成功', $updateResult, 200]);
        } catch (\Exception $e) {
            $errorMsg = '处理过程中发生错误: ' . $e->getMessage() . ' 在文件 ' . $e->getFile() . ' 第 ' . $e->getLine() . ' 行';
            dump($errorMsg);
            trace($errorMsg, 'error');
            dump('堆栈跟踪: ' . $e->getTraceAsString());
            trace('堆栈跟踪: ' . $e->getTraceAsString(), 'error');
            
            // 检查是否在CLI模式下运行
            if (php_sapi_name() === 'cli') {
                echo $errorMsg . "\n";
                return;
            }
            
            // 使用更安全的错误处理方式
            dump([$errorMsg, null, 0]);
        }
    }
    
    /**
     * 更新菜品信息和食材关联
     * @param array $dishData 菜品数据
     * @return array 更新结果
     */
    private function updateDishInfo($dishData)
    {
        $successCount = 0;
        $processedDishes = [];
        
        foreach ($dishData as $dishId => $dishInfo) {
            // 开始事务
            Db::startTrans();
            try {
                dump('开始处理菜品ID: ' . $dishId);
                trace('开始处理菜品ID: ' . $dishId, 'info');
                
                // 1. 更改ai_called为1
                // 2. 更改cook_time烹饪时长，为ai返回的数据
                // 3. 更改steps制作步骤为ai返回的数据
                $updateData = [
                    'ai_called' => 1,
                    'cook_time' => $dishInfo['cook_time'] ?? '',
                    'steps' => $dishInfo['steps'] ?? '',
                    'updatetime' => time()
                ];
                
                Db::name('food_dish')->where('id', $dishId)->update($updateData);
                dump('更新菜品基本信息完成，菜品ID: ' . $dishId);
                trace('更新菜品基本信息完成，菜品ID: ' . $dishId, 'info');
                
                // 4. 新增fa_food_ingredientrel中间表数据
                // 删除原有的食材关联
                Db::name('food_ingredientrel')->where('dish_id', $dishId)->delete();
                dump('删除原有食材关联完成，菜品ID: ' . $dishId);
                trace('删除原有食材关联完成，菜品ID: ' . $dishId, 'info');
                
                // 添加新的食材关联
                if (!empty($dishInfo['ingredients'])) {
                    $insertData = [];
                    foreach ($dishInfo['ingredients'] as $index => $ingredient) {
                        // 先保存AI返回的食材名称和用量
                        $ingredientData = [
                            'dish_id' => $dishId,
                            'ingredient_name' => $ingredient['name'] ?? '', // 保存食材名称
                            'ingredient_id' => 0, // 默认值
                            'parent_id' => null, // 默认值
                            'categories_id' => null, // 默认值
                            'quantity' => $ingredient['quantity'] ?? '100g', // 保存用量
                            'createtime' => time(),
                            'updatetime' => time(),
                            'weigh' => $index + 1
                        ];
                        
                        dump('处理食材: ' . $ingredient['name'] . '，用量: ' . $ingredient['quantity']);
                        trace('处理食材: ' . $ingredient['name'] . '，用量: ' . $ingredient['quantity'], 'info');
                        
                        // 查询fa_food_ingredient表，看是否有这个食材
                        // 先尝试精确匹配
                        $ingredientInfo = Db::name('food_ingredient')
                            ->where('name', $ingredient['name'])
                            ->field('id, parent_id, categories_id')
                            ->find();
                        
                        // 如果没有精确匹配，尝试多种模糊匹配方式
                        if (!$ingredientInfo) {
                            // 方式1: 名称包含食材名
                            $ingredientInfo = Db::name('food_ingredient')
                                ->where('name', 'like', '%' . $ingredient['name'] . '%')
                                ->field('id, parent_id, categories_id')
                                ->find();
                        }
                        
                        if (!$ingredientInfo) {
                            // 方式2: 食材名包含名称中的关键词（处理如"西兰花[绿菜花]"这样的情况）
                            $ingredientInfo = Db::name('food_ingredient')
                                ->where('name', 'like', $ingredient['name'] . '%')
                                ->field('id, parent_id, categories_id')
                                ->find();
                        }
                        
                        // 如果找到了对应的食材，就更新关联信息
                        if ($ingredientInfo) {
                            $ingredientData['ingredient_id'] = $ingredientInfo['id'];
                            $ingredientData['parent_id'] = $ingredientInfo['parent_id'];
                            $ingredientData['categories_id'] = $ingredientInfo['categories_id'];
                            dump('找到匹配的食材，ID: ' . $ingredientInfo['id']);
                            trace('找到匹配的食材，ID: ' . $ingredientInfo['id'], 'info');
                        } else {
                            dump('未找到匹配的食材: ' . $ingredient['name']);
                            trace('未找到匹配的食材: ' . $ingredient['name'], 'info');
                        }
                        $insertData[] = $ingredientData;
                    }
                    
                    if (!empty($insertData)) {
                        dump('准备插入食材关联数据，数量: ' . count($insertData));
                        trace('准备插入食材关联数据，数量: ' . count($insertData), 'info');
                        dump('插入数据详情: ' . json_encode($insertData, JSON_UNESCAPED_UNICODE));
                        trace('插入数据详情: ' . json_encode($insertData, JSON_UNESCAPED_UNICODE), 'info');
                        
                        $result = Db::name('food_ingredientrel')->insertAll($insertData);
                        dump('插入食材关联数据完成，结果: ' . $result);
                        trace('插入食材关联数据完成，结果: ' . $result, 'info');
                    } else {
                        dump('没有食材数据需要插入');
                        trace('没有食材数据需要插入', 'info');
                    }
                } else {
                    dump('菜品没有食材信息');
                    trace('菜品没有食材信息', 'info');
                }
                
                // 提交事务
                Db::commit();
                $successCount++;
                $processedDishes[] = $dishId;
                dump('菜品处理完成，菜品ID: ' . $dishId);
                trace('菜品处理完成，菜品ID: ' . $dishId, 'info');
                
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                $errorMsg = '更新菜品ID ' . $dishId . ' 失败: ' . $e->getMessage();
                dump($errorMsg);
                trace($errorMsg, 'error');
            }
        }
        
        $result = [
            'success_count' => $successCount,
            'processed_dishes' => $processedDishes
        ];
        
        dump('全部菜品处理完成，结果: ' . json_encode($result, JSON_UNESCAPED_UNICODE));
        trace('全部菜品处理完成，结果: ' . json_encode($result, JSON_UNESCAPED_UNICODE), 'info');
        
        return $result;
    }
    
    /**
     * 处理批量菜品信息，匹配食材ID
     * @param array $data 从AI获取的数据
     * @param array $dishes 菜品数组，包含id和name
     * @return array 处理后的数据
     */
    private function processBatchDishInfo($data, $dishes)
    {
        $result = [];
        
        // 获取所有食材信息
        $allIngredients = Db::name('food_ingredient')->field('id,name')->select();
        $ingredientMap = [];
        foreach ($allIngredients as $ingredient) {
            $ingredientMap[$ingredient['name']] = $ingredient['id'];
        }
        
        // 直接通过ID处理，而不是通过名称处理
        foreach ($dishes as $dish) {
            $dishId = $dish['id'];
            $dishName = $dish['name'];
            
            // 检查AI返回的数据中是否有这个菜品的信息（通过ID查找）
            if (isset($data[$dishId])) {
                $result[$dishId] = $data[$dishId];
            }
            // 如果通过ID找不到，尝试通过名称查找（兼容旧格式）
            else if (isset($data[$dishName])) {
                $result[$dishId] = $data[$dishName];
            }
            
            // 处理食材信息
            if (isset($result[$dishId]) && !empty($result[$dishId]['ingredients'])) {
                foreach ($result[$dishId]['ingredients'] as &$ingredient) {
                    $ingredientName = $ingredient['name'];
                    if (isset($ingredientMap[$ingredientName])) {
                        $ingredient['id'] = $ingredientMap[$ingredientName];
                    } else {
                        $ingredient['id'] = 0; // 未找到匹配的食材ID
                    }
                    
                    // 添加单位能量信息
                    if ($ingredient['id'] > 0) {
                        $ingredientInfo = Db::name('food_ingredient')
                            ->where('id', $ingredient['id'])
                            ->field('energy_kilocalorie')
                            ->find();
                        $ingredient['unitEnergy'] = $ingredientInfo['energy_kilocalorie'] ?? 0;
                    } else {
                        $ingredient['unitEnergy'] = 0;
                    }
                }
            }
        }
        
        return $result;
    }
    
    /**
     * 调用阿里云千问API批量查询菜品制作信息
     * @param array $dishes 菜品数组，包含id和name
     * @return array|null 制作信息
     */
    private function batchQueryDishInfoByQwen($dishes)
    {
        // 阿里云千问API配置
        $apiKey = 'sk-416b931b781c420c9f6331b7346962b5';
        $apiUrl = 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions';
        $model = 'qwen-plus';
        
        // 构造菜品信息列表
        $dishList = "";
        foreach ($dishes as $dish) {
            $dishList .= "ID: {$dish['id']}, 名称: {$dish['name']}\n";
        }
        
        // 构造提示词
        $prompt = "菜品信息列表：\n{$dishList}\n\n请根据这些菜品信息，为每个菜品提供以下信息：\n";
        $prompt .= "1. 所需食材列表（包括食材名称和建议用量）\n";
        $prompt .= "2. 烹饪时长（以分钟为单位）\n";
        $prompt .= "3. 制作步骤（详细步骤）\n\n";
        $prompt .= "请严格按照以下JSON格式返回结果，不要包含其他内容：\n";
        $prompt .= "quantity全部采用g为后缀，没有其他重量方法\n";
        $prompt .= "{\n";
        $prompt .= "  \"菜品ID1\": {\n";
        $prompt .= "    \"ingredients\": [\n";
        $prompt .= "      {\"name\": \"鸡蛋\", \"quantity\": \"150g\"},\n";
        $prompt .= "      {\"name\": \"西红柿\", \"quantity\": \"300g\"}\n";
        $prompt .= "    ],\n";
        $prompt .= "    \"cook_time\": \"7分钟\",\n";
        $prompt .= "    \"steps\": \"1. 热锅凉油...\\n2. ...\"\n";
        $prompt .= "  },\n";
        $prompt .= "  \"菜品ID2\": {\n";
        $prompt .= "    \"ingredients\": [...],\n";
        $prompt .= "    \"cook_time\": \"...\",\n";
        $prompt .= "    \"steps\": \"...\"\n";
        $prompt .= "  }\n";
        $prompt .= "}";
        
        $data = [
            'model' => $model,
            'messages' => [
                [
                    'role' => 'user',
                    'content' => $prompt
                ]
            ],
            'temperature' => 0.1,
            'max_tokens' => 4000
        ];
        
        dump('准备调用千问API: ' . $apiUrl . ', 模型: ' . $model . ', 菜品数量: ' . count($dishes));
        trace('准备调用千问API: ' . $apiUrl . ', 模型: ' . $model . ', 菜品数量: ' . count($dishes), 'info');
        
        // 发起HTTP请求
        $headers = [
            'Authorization: Bearer ' . $apiKey,
            'Content-Type: application/json'
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 120); // 增加超时到120秒
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60); // 增加连接超时到60秒
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        
        dump('千问API响应 - HTTP状态码: ' . $httpCode . ', 错误: ' . $error);
        trace('千问API响应 - HTTP状态码: ' . $httpCode . ', 错误: ' . $error, 'info');
        
        if (curl_errno($ch)) {
            dump('千问API调用错误: ' . curl_error($ch));
            trace('千问API调用错误: ' . curl_error($ch), 'error');
            curl_close($ch);
            return null;
        }
        
        curl_close($ch);
        
        if ($httpCode !== 200) {
            $errorMsg = '千问API返回错误状态码: ' . $httpCode;
            dump($errorMsg);
            trace($errorMsg, 'error');
            return null;
        }
        
        if (empty($response)) {
            $errorMsg = '千问API返回空响应';
            dump($errorMsg);
            trace($errorMsg, 'error');
            return null;
        }
        
        $responseArr = json_decode($response, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            $errorMsg = '千问API响应JSON解析错误: ' . json_last_error_msg();
            dump($errorMsg);
            trace($errorMsg, 'error');
            dump('响应内容: ' . $response);
            trace('响应内容: ' . $response, 'error');
            return null;
        }
        
        if (empty($responseArr['choices'][0]['message']['content'])) {
            $errorMsg = '千问API响应内容为空';
            dump($errorMsg);
            trace($errorMsg, 'error');
            dump('完整响应: ' . json_encode($responseArr, JSON_UNESCAPED_UNICODE));
            trace('完整响应: ' . json_encode($responseArr, JSON_UNESCAPED_UNICODE), 'error');
            return null;
        }
        
        // 解析返回的JSON内容
        $content = trim($responseArr['choices'][0]['message']['content']);
        dump('API返回内容: ' . $content);
        trace('API返回内容: ' . $content, 'info');
        
        // 尝试提取JSON部分
        if (preg_match('/\{.*\}/s', $content, $matches)) {
            $jsonStr = $matches[0];
            $result = json_decode($jsonStr, true);
            if (json_last_error() === JSON_ERROR_NONE) {
                dump('成功解析JSON数据');
                trace('成功解析JSON数据', 'info');
                return $result;
            } else {
                $errorMsg = '提取的JSON内容解析失败: ' . json_last_error_msg();
                dump($errorMsg);
                trace($errorMsg, 'error');
                dump('提取的JSON内容: ' . $jsonStr);
                trace('提取的JSON内容: ' . $jsonStr, 'error');
            }
        }
        
        dump('无法从响应中提取有效的JSON数据');
        trace('无法从响应中提取有效的JSON数据', 'error');
        return null;
    }
    
    /**
     * 根据菜品ID获取制作信息（调用阿里云千问API）
     * @ApiMethod (POST)
     * @ApiTitle (获取菜品制作信息)
     * @ApiSummary (根据菜品名称获取所需食材列表、烹饪时长、制作步骤)
     * @ApiParams (name="dish_id", type="integer", required=true, description="菜品ID")
     * @ApiReturn ({ "code": 1, "msg": "获取成功", "data": { "ingredients": [{"id": 1, "name": "鸡蛋", "quantity": 150, "unitEnergy": 143}], "cook_time": "7分钟", "steps": "1、热锅凉油..." } })
     */
    public function getDishInfo()
    {
        $dishId = $this->request->post('dish_id');
        if (empty($dishId)) {
            $this->error('菜品ID不能为空');
        }
        
        // 获取菜品信息
        $dish = Db::name('food_dish')->where('id', $dishId)->find();
        if (!$dish) {
            $this->error('菜品不存在');
        }
        
        $dishName = $dish['name'];
        if (empty($dishName)) {
            $this->error('菜品名称不能为空');
        }
        
        // 调用阿里云千问API获取制作信息
        $result = $this->queryDishInfoByQwen($dishName);
        if (empty($result)) {
            $this->error('获取菜品制作信息失败');
        }
        
        // 处理返回的数据，匹配食材ID
        $processedResult = $this->processDishInfo($result);
        
        $this->success('获取成功', $processedResult);
    }
    
    /**
     * 处理菜品信息，匹配食材ID
     * @param array $data 从AI获取的数据
     * @return array 处理后的数据
     */
    private function processDishInfo($data)
    {
        if (empty($data['ingredients'])) {
            return $data;
        }
        
        // 获取所有食材信息
        $allIngredients = Db::name('food_ingredient')->field('id,name')->select();
        $ingredientMap = [];
        foreach ($allIngredients as $ingredient) {
            $ingredientMap[$ingredient['name']] = $ingredient['id'];
        }
        
        // 为每个食材匹配ID
        foreach ($data['ingredients'] as &$ingredient) {
            $ingredientName = $ingredient['name'];
            if (isset($ingredientMap[$ingredientName])) {
                $ingredient['id'] = $ingredientMap[$ingredientName];
            } else {
                $ingredient['id'] = 0; // 未找到匹配的食材ID
            }
            
            // 添加单位能量信息
            if ($ingredient['id'] > 0) {
                $ingredientInfo = Db::name('food_ingredient')
                    ->where('id', $ingredient['id'])
                    ->field('energy_kilocalorie')
                    ->find();
                $ingredient['unitEnergy'] = $ingredientInfo['energy_kilocalorie'] ?? 0;
            } else {
                $ingredient['unitEnergy'] = 0;
            }
        }
        
        return $data;
    }
    
    /**
     * 调用阿里云千问API查询菜品制作信息
     * @param string $dishName 菜品名称
     * @return array|null 制作信息
     */
    private function queryDishInfoByQwen($dishName)
    {
        // 阿里云千问API配置
        $apiKey = 'sk-416b931b781c420c9f6331b7346962b5';
        $apiUrl = 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions';
        $model = 'qwen-plus';
        
        // 构造提示词
        $prompt = "菜品名称：{$dishName}\n\n请根据这个菜品名称，提供以下信息：\n";
        $prompt .= "1. 所需食材列表（包括食材名称和建议用量，格式如：鸡蛋：150克）\n";
        $prompt .= "2. 烹饪时长（以分钟为单位）\n";
        $prompt .= "3. 制作步骤（详细步骤，每步一行）\n\n";
        $prompt .= "请严格按照以下JSON格式返回结果：\n";
        $prompt .= "{\n";
        $prompt .= "  \"ingredients\": [\n";
        $prompt .= "    {\"name\": \"鸡蛋\", \"quantity\": \"150克\"},\n";
        $prompt .= "    {\"name\": \"西红柿\", \"quantity\": \"300克\"}\n";
        $prompt .= "  ],\n";
        $prompt .= "  \"cook_time\": \"7分钟\",\n";
        $prompt .= "  \"steps\": \"1. 热锅凉油...\\n2. ...\"\n";
        $prompt .= "}";
        
        $data = [
            'model' => $model,
            'messages' => [
                [
                    'role' => 'user',
                    'content' => $prompt
                ]
            ],
            'temperature' => 0.1,
            'max_tokens' => 2000
        ];
        
        // 发起HTTP请求
        $headers = [
            'Authorization: Bearer ' . $apiKey,
            'Content-Type: application/json'
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        
        $response = curl_exec($ch);
        
        if (curl_errno($ch)) {
            dump('千问API调用错误: ' . curl_error($ch));
            trace('千问API调用错误: ' . curl_error($ch), 'error');
            curl_close($ch);
            return null;
        }
        
        curl_close($ch);
        
        $responseArr = json_decode($response, true);
        if (empty($responseArr['choices'][0]['message']['content'])) {
            return null;
        }
        
        // 解析返回的JSON内容
        $content = trim($responseArr['choices'][0]['message']['content']);
        
        // 尝试提取JSON部分
        if (preg_match('/\{.*\}/s', $content, $matches)) {
            $jsonStr = $matches[0];
            $result = json_decode($jsonStr, true);
            if (json_last_error() === JSON_ERROR_NONE) {
                return $result;
            }
        }
        
        // 如果JSON解析失败，尝试其他方式解析
        return $this->parseDishInfoFromText($content);
    }
    
    /**
     * 从文本中解析菜品信息
     * @param string $content API返回的文本内容
     * @return array 解析后的数据
     */
    private function parseDishInfoFromText($content)
    {
        $result = [
            'ingredients' => [],
            'cook_time' => '',
            'steps' => ''
        ];
        
        // 提取烹饪时长
        if (preg_match('/(\d+)\s*分钟/', $content, $timeMatches)) {
            $result['cook_time'] = $timeMatches[1] . '分钟';
        }
        
        // 提取制作步骤
        if (preg_match('/制作步骤[:：]?\s*(.*)/s', $content, $stepsMatches)) {
            $steps = trim($stepsMatches[1]);
            // 清理步骤格式
            $steps = preg_replace('/^\s*\d+[\.\、]/m', '', $steps); // 移除步骤编号
            $result['steps'] = trim($steps);
        }
        
        // 提取食材信息
        $lines = explode("\n", $content);
        foreach ($lines as $line) {
            // 匹配食材名称和重量，如：鸡蛋：150克
            if (preg_match('/^([\x{4e00}-\x{9fa5}a-zA-Z]+)[:：]\s*(\d+(?:\.\d+)?)\s*([克gG])?/u', trim($line), $matches)) {
                $ingredientName = $matches[1];
                $quantity = floatval($matches[2]);
                $unit = isset($matches[3]) ? $matches[3] : '克';
                
                $result['ingredients'][] = [
                    'name' => $ingredientName,
                    'quantity' => $quantity . $unit
                ];
            }
        }
        
        return $result;
    }
}